import axios from 'axios';
import { showToast } from 'vant';
import router from '@/router';
const baseUrl = import.meta.env.VITE_BASE_URL;
// 创建axios实例
const service = axios.create({
  baseURL: baseUrl, // API的base_url
  timeout: 15000 // 请求超时时间
});

// 请求计数器，用于跟踪重复请求
const pendingRequests = new Map();

// 生成请求的唯一键
const generateRequestKey = (config) => {
  const { url, method, params, data } = config;
  return `${method}:${url}:${JSON.stringify(params)}:${JSON.stringify(data)}`;
};

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 从本地存储获取userId
    const userId = localStorage.getItem('userId');
    
    // 如果存在userId，则添加到请求头中
    if (userId) {
      config.headers['userId'] = userId;
    }
    
    // 生成请求的唯一键
    const requestKey = generateRequestKey(config);
    
    // 如果该请求正在进行中，则取消本次请求
    if (pendingRequests.has(requestKey) && !config.allowDuplicate) {
      const controller = new AbortController();
      config.signal = controller.signal;
      controller.abort('重复请求被取消');
    } else {
      // 标记该请求正在进行中
      pendingRequests.set(requestKey, true);
      
      // 添加请求完成后的清理函数
      config.requestKey = requestKey;
    }
    
    return config;
  },
  error => {
    console.log(error);
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 请求完成后，从pendingRequests中移除
    if (response.config.requestKey) {
      pendingRequests.delete(response.config.requestKey);
    }
    
    const res = response.data;
    
    // 如果返回的code不是200，则认为请求出错
    if (res.code !== 200) {
      showToast({
        message: res.msg || '服务器错误',
        type: 'fail',
        duration: 2000
      });
      
      // 如果是401，则跳转到登录页面
      if (res.code === 401) {
        // 清除本地存储的用户信息
        localStorage.removeItem('userId');
        localStorage.removeItem('userInfo');
        
        // 跳转到登录页面
        router.replace('/login');
      }
      
      return Promise.reject(new Error(res.msg || '服务器错误'));
    } else {
      return res;
    }
  },
  error => {
    // 请求完成后，从pendingRequests中移除
    if (error.config && error.config.requestKey) {
      pendingRequests.delete(error.config.requestKey);
    }
    
    // 如果是取消请求导致的错误，则不显示错误信息
    if (axios.isCancel(error)) {
      console.log('请求被取消:', error.message);
      return Promise.reject(error);
    }
    
    console.log('err' + error);
    
    let errorMessage = '请求失败';
    
    if (error.response) {
      // 服务器返回了错误状态码
      const status = error.response.status;
      switch (status) {
        case 404:
          errorMessage = '请求的资源不存在';
          break;
        case 500:
          errorMessage = '服务器内部错误';
          break;
        case 502:
        case 503:
          errorMessage = '服务暂时不可用';
          break;
        case 504:
          errorMessage = '网关超时';
          break;
        default:
          errorMessage = `请求失败(${status})`;
      }
    } else if (error.request) {
      // 请求发送了但没有收到响应
      if (error.code === 'ECONNABORTED') {
        errorMessage = '请求超时，请检查网络';
      } else {
        errorMessage = '无法连接到服务器';
      }
    }
    
    // 显示错误信息
    showToast({
      message: errorMessage,
      type: 'fail',
      duration: 2000
    });
    
    return Promise.reject(error);
  }
);

// 封装请求重试函数
export const requestWithRetry = async (requestConfig, retries = 3, delay = 1000) => {
  try {
    return await service(requestConfig);
  } catch (error) {
    // 如果没有重试次数或是取消请求，则直接抛出错误
    if (retries === 0 || axios.isCancel(error)) {
      throw error;
    }
    
    // 等待一段时间后重试
    await new Promise(resolve => setTimeout(resolve, delay));
    console.log(`重试请求 ${requestConfig.url}，剩余重试次数: ${retries - 1}`);
    
    // 递归调用，重试次数减一
    return requestWithRetry(requestConfig, retries - 1, delay);
  }
};

export default service; 